package ca.uvic.cs.cogz.mapping.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Rectangle2D;

import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.border.BevelBorder;

import ca.uvic.cs.cogz.mapping.core.MappingTypeManager.MappingType;
import ca.uvic.cs.cogz.stats.NodeStats;
import ca.uvic.cs.cogz.stats.StatsManager;
import edu.stanford.smi.protege.model.Cls;
import edu.stanford.smi.protegex.prompt.event.PromptEvent;
import edu.stanford.smi.protegex.prompt.event.PromptListener;
import edu.stanford.smi.protegex.prompt.event.PromptListenerManager;
import edu.stanford.smi.protegex.prompt.operation.Operation;
import edu.stanford.smi.protegex.prompt.ui.TabComponent;
import edu.stanford.smi.protegex.prompt.ui.diffUI.DiffTableView;

public class MappingProgressPanel extends JPanel {
	private static final long serialVersionUID = -4309541154565990829L;

	/** width and height of the progress meter */
	private static final int WIDTH = 100;
	private static final int HEIGHT = 20;

	/** reference to the MappingVisualizationPanel so we can apply filters */
	private MappingVisualizationPanel parentPanel;

	/** stats for the root ontology item, used for our progress meter */
	private NodeStats nodeStats;

	/** true if this panel represents the progress in the source ontology */
	private boolean isSource;

	/** rectangles for progress of mapped items and candidate items */
	private Rectangle2D mappedItemsRect;
	private Rectangle2D candidateItemsRect;

	private double lastX;

	public MappingProgressPanel(MappingVisualizationPanel parentPanel, StatsManager statsManager, Cls rootCls, boolean isSource) {
		this.parentPanel = parentPanel;
		this.nodeStats = statsManager.getNodeStats(rootCls);
		this.isSource = isSource;

		setSize(WIDTH, HEIGHT);
		setPreferredSize(new Dimension(WIDTH, HEIGHT));

		initListeners();
	}

	public void paint(Graphics g) {
		super.paint(g);
		Graphics2D g2 = (Graphics2D) g;

		if (nodeStats != null) {
			int withCandidates = nodeStats.getNumOfNodesWithCandidates();
			int withMappings = nodeStats.getNumOfNodesWithMappings();

			int total = withCandidates + withMappings;

			if (total == 0) {
				return;
			}

			lastX = 0;

			BevelBorder progressBorder = new BevelBorder(BevelBorder.LOWERED);
			//GradientPaint gp1 = new GradientPaint(0, 0, new Color(0, 128, 0), 5, 5, new Color(64, 255, 64), true);
			mappedItemsRect = drawRect(g2, new Color(0, 128, 0), withMappings, total);

			//bb.paintBorder(this, g, (int) mappedItemsRect.getX(), (int) mappedItemsRect.getY(), (int) mappedItemsRect.getWidth(), (int) mappedItemsRect.getHeight());

			//GradientPaint gp2 = new GradientPaint(0, 0, new Color(127, 0, 0), 5, 5, Color.orange, true);
			candidateItemsRect = drawRect(g2, new Color(127, 0, 0), withCandidates, total);

			progressBorder.paintBorder(this, g, (int) mappedItemsRect.getX(), (int) mappedItemsRect.getY(), (int) candidateItemsRect.getWidth() + (int) mappedItemsRect.getWidth(),
					(int) candidateItemsRect.getHeight());
		}
	}

	private Rectangle2D drawRect(Graphics2D g, Paint paint, int subsetCount, int total) {
		double width = (double) subsetCount / total * getWidth();

		double y = getHeight() / 2 - HEIGHT / 2;
		Rectangle2D rect = new Rectangle2D.Double(lastX, y, width, HEIGHT);
		g.setPaint(paint);
		g.fill(rect);

		lastX = width;

		return rect;
	}

	private void initListeners() {
		// listen for mouse overs and set the appropriate tooltip text on the panel
		this.addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseMoved(MouseEvent e) {
				if (mappedItemsRect != null && mappedItemsRect.contains(e.getPoint())) {
					if (nodeStats.getNumOfNodesWithMappings() == 1) {
						setToolTipText(nodeStats.getNumOfNodesWithMappings() + " mapped item");
					} else {
						setToolTipText(nodeStats.getNumOfNodesWithMappings() + " mapped items");
					}
				} else if (candidateItemsRect != null && candidateItemsRect.contains(e.getPoint())) {
					if (nodeStats.getNumOfNodesWithCandidates() == 1) {
						setToolTipText(nodeStats.getNumOfNodesWithCandidates() + " candidate item");
					} else {
						setToolTipText(nodeStats.getNumOfNodesWithCandidates() + " candidate items");
					}
				}
			}
		});

		// listen for mouse clicks and apply the appropriate filter
		/*this.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				if (mappedItemsRect.contains(e.getPoint())) {
					if (isSource) {
						parentPanel.applyMappingSourceFilter(MappingType.VERIFIED_MAPPING);
					} else {
						parentPanel.applyMappingTargetFilter(MappingType.VERIFIED_MAPPING);
					}
				} else if (candidateItemsRect.contains(e.getPoint())) {
					if (isSource) {
						parentPanel.applyMappingSourceFilter(MappingType.CANDIDATE_MAPPING);
					} else {
						parentPanel.applyMappingTargetFilter(MappingType.CANDIDATE_MAPPING);
					}
				}
			}
		});*/

		// listen for operations and force a repaint
		PromptListenerManager.addListener(new PromptListener() {
			public void UIBuilt(TabComponent promptTab, PromptEvent event) {}

			public void diffDone(PromptEvent event) {}

			public void diffTableViewBuilt(DiffTableView view, PromptEvent event) {}

			public void diffUIBuilt(JTabbedPane mainPane, PromptEvent event) {}

			public void initializationDone(PromptEvent event) {}

			public void taskComplete(PromptEvent event, boolean interrupted) {}

			public void operationStarted(Operation operation, PromptEvent event) {}

			public void operationCompleted(Operation operation, PromptEvent event) {
				repaint();
			}
		});
	}
}
